// hdu5785
// 题意：
// 给定一个长度小于等于1000000的字符串s，现在要求有多少三元组(i, j, k)
// 满足1<=i<=j<k<=len(s)，且s[i..j]和s[j+1..k]都是回文子串，现在我们要
// 求i*k的和答案再mod 1000000007。
//
// 题解：
// 我们分析下，相当于要求出以某个位置i位有边界的所有回文子串的左边界
// 下标的和l[i]，以及类似的r[i]，只要求出这两个东西答案就很好计算了。
//
// 考虑计算l[i]，首先可以马拉车得到所有回文半径。为了简化讨论我们就考虑
// 奇数长度回文串的情况，假设回文半径是d[i]，那么[i, i + d[i]]内以i为
// 左边界的子串都是回文串，现在就是要怎么把i加到那些位置，其实这相当于
// 是一个区间覆盖问题，因为没有修改，所以不用树状数组或者线段树，用数组
// 标记下区间边界，然后O(n)求前缀和就行。
//
// 然后比较麻烦的是要分奇数偶数讨论，然后要维护的数组可能比较多。
//
#include <iostream>
#include <cstring>
#include <string>

int const maxn = 1000007;
long long const mo = 1000000007;

namespace manacher
{
	int d1[maxn];
	int d2[maxn];
	int num[maxn], num2[maxn];
	long long tot[maxn], tot2[maxn], cl[maxn], cr[maxn];

	void add(long long & x, long long y)
	{
		x = (((x + y) % mo) + mo) % mo;
	}

	long long manacher(std::string const& s)
	{
		int n = s.size();
		std::memset(cl, 0, sizeof(cl));
		std::memset(cr, 0, sizeof(cr));
		std::memset(num, 0, sizeof(num));
		std::memset(tot, 0, sizeof(tot));
		std::memset(num2, 0, sizeof(num2));
		std::memset(tot2, 0, sizeof(tot2));
		// for odd len
		int l = 0, r = -1;
		for (int i = 0; i < n; i++) {
			int k = (i > r ? 0 : std::min(d1[l + r - i], r - i)) + 1;
			while (i + k < n && i - k >= 0 && s[i + k] == s[i - k]) k++;
			d1[i] = --k; // origin: d1[i] = k--;
			if (i + k > r) { l = i - k; r = i + k; }
			num[i - d1[i]]++; num[i + 1]--;
			add(tot[i - d1[i]], i + 1); add(tot[i + 1], -(i + 1));
			num2[i + d1[i]]++; if (i) num2[i - 1]--;
			add(tot2[i + d1[i]], i + 1); if (i) add(tot2[i - 1], -(i + 1));
		}

		long long count = 0, sum = 0;
		for (int i = 0; i < n; i++) {
			count += num[i];
			sum += tot[i];
			if (sum > mo) sum -= mo;
			cl[i] = (2 * sum - (i + 1) * count) % mo;
		}
		count = sum = 0;
		for (int i = n - 1; i >= 0; i--) {
			count += num2[i];
			sum += tot2[i];
			if (sum > mo) sum -= mo;
			cr[i] = (2 * sum - (i + 1) * count) % mo;
		}

		std::memset(num, 0, sizeof(num));
		std::memset(tot, 0, sizeof(tot));
		std::memset(num2, 0, sizeof(num2));
		std::memset(tot2, 0, sizeof(tot2));
		l = 0; r = -1;
		// for even len
		for (int i = 0; i < n; i++) {
			int k = (i > r ? 0 : std::min(d2[l + r - i + 1], r - i + 1)) + 1;
			while (i + k - 1 < n && i - k >= 0 && s[i + k - 1] == s[i - k]) k++;
			d2[i] = --k;
			if (i + k - 1 > r) { l = i - k; r = i + k - 1; }
			num[i - d2[i]]++; num[i]--;
			add(tot[i - d2[i]], i + 1); add(tot[i], -(i + 1));
			num2[i + d2[i] - 1]++; if (i) num2[i - 1]--;
			add(tot2[i + d2[i] - 1], i + 1); if (i) add(tot2[i - 1], -(i + 1));
		}

		count = sum = 0;
		for (int i = 0; i < n; i++) {
			count += num[i];
			sum += tot[i];
			if (sum > mo) sum -= mo;
			cl[i] += (2 * sum - (i + 2) * count) % mo;
			cl[i] %= mo;
		}
		count = sum = 0;
		for (int i = n - 1; i >= 0; i--) {
			count += num2[i];
			sum += tot2[i];
			if (sum > mo) sum -= mo;
			cr[i] += (2 * sum - (i + 2) * count) % mo;
			cr[i] %= mo;
		}

		long long ret = 0;
		for (int i = 0; i < n; i++) {
			/* std::cout << cl[i] << " " << cr[i] << "\n"; */
			ret += (cr[i] * cl[i + 1]) % mo;
			ret %= mo;
		}

		return (ret + mo) % mo;
	}
}

int main()
{
	for (std::string s; std::cin >> s; )
		std::cout << manacher::manacher(s) << "\n";
}

